/*
 *
 * Copyright 2011-2013 University of Illinois
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *    http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 */

Components.utils.import("resource://oaa-accessibility-extension/cache-inspector-common.js");
Components.utils.import("resource://gre/modules/FileUtils.jsm");
Components.utils.import("resource://gre/modules/NetUtil.jsm");

// import getLogger
Components.utils.import("resource://oaa-ae-utilities/logger.js", OAA_AE);


OAA_AE.SIDEBAR_URL = "chrome://oaa-accessibility-extension/content/sidebar.xul";


/**
 * @function exportRules
 *
 * @memberOf OAA_AE
 *
 * @desc Opens the preferences dialog box
 */

OAA_AE.exportRules = function () {

  var dir = FileUtils.getDir('Desk', ['OAA Rules'], true, true);

  var file = FileUtils.getFile('Desk', ['OAA Rules', 'oaa_exported_rules.json']);
  
  var fileStream = FileUtils.openSafeFileOutputStream(file, 0x02 | 0x08 | 0x20, 0x644, 0);  
  
  var json = "{ \"wcag20\"  : " + OpenAjax.a11y.wcag20_nls.nls['en-us'].toJSON("\n    ") + ",\n";
  json += "  \"rule_categories\" : " + OpenAjax.a11y.rule_categories_nls.nls['en-us'].toJSON("\n    ") + ",\n";
  json += "  \"rule_scopes\" : " + OpenAjax.a11y.rule_scopes_nls.nls['en-us'].toJSON("\n    ") + ",\n";
  json += "  \"rules\" : " + OpenAjax.a11y.all_rules.toJSON("    ") + ",\n";
  json += "  \"rulesets\" : " + OpenAjax.a11y.all_rulesets.toJSON("    ") + "\n";
  json += "}\n";

  // encode string at UTF-8
  json = unescape(encodeURIComponent(json)); 

  fileStream.write(json, json.length);
  
  FileUtils.closeSafeFileOutputStream(fileStream);

  OAA_AE.logger.debug("Report URL: " + file.path);


  file = FileUtils.getFile('Desk', ['OAA Rules', 'oaa_exported_rules.html']);
  
  fileStream = FileUtils.openSafeFileOutputStream(file, 0x02 | 0x08 | 0x20, 0x644, 0);  
  
  var title = 'Exported OAA Rule and Ruleset Information';
  
  var html = "";
  html += "<!DOCTYPE html>";
  html += "<html lang='en-us'>\n";
  html += "  <head>\n";
  html += "    <title id='ID_TITLE'>" + title + "</title>\n";
  html += "    <script type='text/javascript'>\n";
  html += "      var wcag20 = " + OpenAjax.a11y.wcag20_nls.nls['en-us'].toJSON("\n      ") + ";\n";
  html += "      var rules = " + OpenAjax.a11y.all_rules.toJSON("      ");
  html += "      var rulesets = " + OpenAjax.a11y.all_rulesets.toJSON("      ");
  html += "    </script>\n";
  html += OpenAjax.a11y.rule_export_js;
  html += OpenAjax.a11y.rule_export_css;
  html += "  </head>\n";
  html += OpenAjax.a11y.rule_export_body;
  html += "</html>\n";
  
  fileStream.write(html, html.length);
  
  FileUtils.closeSafeFileOutputStream(fileStream);
    
  OAA_AE.logger.debug("Report URL: " + file.path);
  
  var interface1 = window.QueryInterface(Components.interfaces.nsIInterfaceRequestor);
  var interface2 = interface1.getInterface(Components.interfaces.nsIWebNavigation);
  var interface3 = interface2.QueryInterface(Components.interfaces.nsIDocShellTreeItem);
  var interface4 = interface3.rootTreeItem.QueryInterface(Components.interfaces.nsIInterfaceRequestor);
  var mainWindow = interface4.getInterface(Components.interfaces.nsIDOMWindow);
 
  if (mainWindow) mainWindow.gBrowser.addTab(file.path);

};


/**
 * @function OAA_AE.exportEvaluationResults
 *
 * @desc Opens the preferences dialog box
 */

OAA_AE.exportEvaluationResults = function () {

  var dir = FileUtils.getDir('Desk', ['OAA Rules'], true, true);

  var file = FileUtils.getFile('Desk', ['OAA Rules', 'page_evaluation_results.json']);
  
  var fileStream = FileUtils.openSafeFileOutputStream(file, 0x02 | 0x08 | 0x20, 0x644, 0);  
  
  var sidebar_window = OAA_AE.getSidebarWindow();

  OAA_AE.logger.debug("Exporting Evaluation Results: " + sidebar_window );

  if ((typeof sidebar_window !== 'object') || (typeof sidebar_window.OAA_AE_SIDEBAR !== 'object')) return;

  var json = sidebar_window.OAA_AE_SIDEBAR.evaluation_result.toJSON();
  
  fileStream.write(json, json.length);
  
  FileUtils.closeSafeFileOutputStream(fileStream);
    
  OAA_AE.logger.debug("Report URL: " + file.path);
  
  var interface1 = window.QueryInterface(Components.interfaces.nsIInterfaceRequestor);
  var interface2 = interface1.getInterface(Components.interfaces.nsIWebNavigation);
  var interface3 = interface2.QueryInterface(Components.interfaces.nsIDocShellTreeItem);
  var interface4 = interface3.rootTreeItem.QueryInterface(Components.interfaces.nsIInterfaceRequestor);
  var mainWindow = interface4.getInterface(Components.interfaces.nsIDOMWindow);
 
  if (mainWindow) mainWindow.gBrowser.addTab(file.path);

};

/**
 * @function exportEvaluation
 *
 * @memberOf OAA_AE
 *
 * @desc Exports an evaluation to disk and opens a window wiht the 
 */

OAA_AE.exportEvaluation = function () {

  var dir = FileUtils.getDir('TmpD', [], true, true);

  var file = FileUtils.getFile('TmpD', ['oaa_report_evaluation.py']);
  
  var fileStream = FileUtils.openSafeFileOutputStream(file, 0x02 | 0x08 | 0x20, 0x644, 0);  
    
  var doc;
  var title;
  var url;

  try {
      doc = window.content.document;
      title = doc.title;
      url = window.content.location.href;
  } catch(e) {
      doc  = window.opener.parent.content.document;
      title = doc.title;
      url = window.opener.parent.location.href;
  } // end try
  
  var prefs = OAA_WEB_ACCESSIBILITY_PREF.util.getPreferences();
 
  var ruleset = OpenAjax.a11y.all_rulesets.getRuleset(prefs.ruleset_id); 

  var python_code = "Ruleset not initialized\n";  

  if (ruleset) {

    ruleset.setEvaluationLevels(prefs.evaluation_levels);
    ruleset.setRecommendedRulesEnabled(prefs.recommended_rules_enabled);
    ruleset.setBrokenLinkTesting(prefs.broken_links);
  
    OAA_AE.logger.debug("                Page Title: " + title);
    OAA_AE.logger.debug("                Page   URL: " + url);
    OAA_AE.logger.debug("                Ruleset ID: " + ruleset.ruleset_id);
    OAA_AE.logger.debug("          Evaluation Level: " + ruleset.evaluation_levels);
    OAA_AE.logger.debug(" Recommended Rules Enabled: " + ruleset.recommended_rules_enabled);
    OAA_AE.logger.debug("              Broken Links: " + OpenAjax.a11y.URL_TESTING_ENABLED);

    ruleset.evaluate(url, title, doc, null, true);
    
    var python_code = ruleset.exportEvaluationResultsToPython();   

  }
    
  fileStream.write(python_code, python_code.length);
  
  FileUtils.closeSafeFileOutputStream(fileStream);
    
  OAA_AE.logger.debug("Evaluation Report URL: " + file.path);
  
  var interface1 = window.QueryInterface(Components.interfaces.nsIInterfaceRequestor);
  var interface2 = interface1.getInterface(Components.interfaces.nsIWebNavigation);
  var interface3 = interface2.QueryInterface(Components.interfaces.nsIDocShellTreeItem);
  var interface4 = interface3.rootTreeItem.QueryInterface(Components.interfaces.nsIInterfaceRequestor);
  var mainWindow = interface4.getInterface(Components.interfaces.nsIDOMWindow);
 
  if (mainWindow) mainWindow.gBrowser.addTab(file.path);

};

/**
 * @function OAA_AE.moveFocusToRuleList
 *
 * @desc Move focus to rule list in the OAA sidebar 
 */
 
OAA_AE.moveFocusToRuleList = function() {

  var sidebarWindow = window.document.getElementById("sidebar").contentWindow;
  
//  OAA_AE.logger.debug("Move focus to rule list: " + sidebarWindow);

  if (sidebarWindow) {
  
    var vbox_rule_category       = sidebarWindow.document.getElementById('ID_VBOX_RULE_CATEGORY_VIEW');  
    var tree_rule_category       = sidebarWindow.document.getElementById('ID_TREE_RULE_CATEGORY_VIEW');  

    var vbox_element_result_view = sidebarWindow.document.getElementById('ID_VBOX_ELEMENT_RESULT_VIEW');  
    var tree_element_result_view   = sidebarWindow.document.getElementById('ID_TREE_ELEMENT_RESULT_VIEW');  

    if (vbox_rule_category && 
        !vbox_rule_category.hidden && 
        tree_rule_category) tree_rule_category.focus();  
        
    if (vbox_element_result_view && 
        !vbox_element_result_view.hidden && 
        tree_element_result_view) tree_element_result_view.focus();      
      
  }  

};

/**
 * @function OAA_AE.moveFocusToElementList
 *
 * @desc Move focus to rule list in the OAA sidebar 
 */
 
OAA_AE.moveFocusToElementList = function() {

  var sidebarWindow = window.document.getElementById("sidebar").contentWindow;
  
//  OAA_AE.logger.debug("Move focus to element list: " + sidebarWindow);

  if (sidebarWindow) {
  
    var vbox_rule_result_view    = sidebarWindow.document.getElementById('ID_VBOX_RULE_RESULT_VIEW');  
    var tree_rule_result_list    = sidebarWindow.document.getElementById('ID_TREE_RULE_RESULT_LIST');  

    var vbox_element_view        = sidebarWindow.document.getElementById('ID_VBOX_ELEMENT_VIEW');  
    var tree_element_view_items  = sidebarWindow.document.getElementById('ID_TREE_ELEMENT_VIEW_ITEMS');  

    if (vbox_rule_result_view && 
        !vbox_rule_result_view.hidden && 
        tree_rule_result_list) tree_rule_result_list.focus();  
        
    if (vbox_element_view && 
        !vbox_element_view.hidden && 
        tree_element_view_items) tree_element_view_items.focus();      
      
  }  

};

/**
 * @function OAA_AE.moveFocusToViewButton
 *
 * @desc Move focus to rule list in the OAA sidebar 
 */
 
OAA_AE.moveFocusToViewButton = function() {

  var sidebarWindow = window.document.getElementById("sidebar").contentWindow;
  
//  OAA_AE.logger.debug("side bar window: " + sidebarWindow);

  if (sidebarWindow) {
  
    var button_view_options = sidebarWindow.document.getElementById('ID_BUTTON_VIEW_OPTIONS');  

    if (button_view_options) button_view_options.focus();  
              
  }  

};


/**
 * @function openReport
 *
 * @memberOf OAA_AE
 *
 * @desc Open a OAA report for a view 
 */
 
OAA_AE.openReport = function() {

  var node_focus = null;

  var sidebarWindow = window.document.getElementById("sidebar").contentWindow;
  
//  OAA_AE.logger.debug("side bar window: " + sidebarWindow);

  if (sidebarWindow) {
  
    var vbox_rule_category   = sidebarWindow.document.getElementById('ID_VBOX_RULE_CATEGORY_VIEW');  
    var vbox_element        = sidebarWindow.document.getElementById('ID_VBOX_ELEMENT_VIEW');  

    if (vbox_rule_category && !vbox_rule_category.hidden) sidebarWindow.OAA_AE_SIDEBAR.RuleCategoryView.createReport();      
    if (vbox_element       && !vbox_element.hidden)       sidebarWindow.OAA_AE_SIDEBAR.ElementView.createReport(); 
      
  }  

};


/**
 * @function setFocusDetails
 *
 * @memberOf OAA_AE
 *
 * @desc Move keyboard focus to the summary list in the OAA sidebar 
 */

OAA_AE.setFocusDetails = function() {

  var node_focus = null;

  var sidebarWindow = window.document.getElementById("sidebar").contentWindow;
  
  if (sidebarWindow) {
  
    var vbox_rule_result    = sidebarWindow.document.getElementById('ID_VBOX_RULE_RESULT_VIEW');  
    var vbox_element_result = sidebarWindow.document.getElementById('ID_VBOX_ELEMENT_RESULT_VIEW');  

    if (vbox_rule_result    && !vbox_rule_result.hidden)    node_focus = sidebarWindow.document.getElementById('ID_TREE_RULE_RESULT_LIST');
    if (vbox_element_result && !vbox_element_result.hidden) node_focus = sidebarWindow.document.getElementById('ID_TREE_ELEMENT_RESULT_VIEW');

    if (node_focus) node_focus.focus();
    
  }  
};

/**
 * @function initToolbarButtonAndMenu
 *
 * @memberOf OAA_AE
 *
 * @desc onload function sets toolbar and menu visibility
 */

OAA_AE.initToolbarButtonAndMenu = function() {

  function getButtonFromPalette() {
  
    var palette = gNavToolbox.palette;
    for (var i = 0; i < palette.childNodes.length; ++i) {
      var child = palette.childNodes[i];
      if (child.id && child.id == ID_BUTTON) return child;
    }
    return null;
  }
 
  var prefs = OAA_WEB_ACCESSIBILITY_PREF.util.getPreferences();

  // Use user preferences to enable the accessibility menu

  var menu = document.getElementById('ID_MENU_OAA_CACHE_INSPECTOR');
  
  if (menu && prefs.show_accessibility_menu) {
    menu.setAttribute('hidden', 'false');
  } 

};

/** 
 * @function showPreferences
 *
 * @memberOf OAA_AE
 *
 * @desc shows the preferences dialog box
 */

OAA_AE.showPreferences = function() {

  window.open("chrome://oaa-accessibility-extension/content/preferences-dialog.xul", "oaaPreferencesDialog", "chrome,centerscreen");
  
};


/** 
 * @function showAbout
 *
 * @memberOf OAA_AE
 *
 * @desc shows the log information for the last evaluation
 *
 * @param {String}  format  - String format of the the log file, valid values TEXT, XML, JSON and HTML
 */

OAA_AE.showAbout = function() {

  window.open("chrome://oaa-accessibility-extension/content/about.xul", "aboutDialog", "chrome,centerscreen");
  
};

// create constant for tab attribute
OAA_AE.TAB_ATTRIBUTE_NAME = "oaaisopen";

// create namespace in parent window context
parent.OAA_AE_TAB = {
  last_view_id : null,
  update_context : null,
  preferences_callback: null
};


/**
 * @function isSidebarVisible
 *
 * @memberOf OAA_AE
 *
 * @desc Helper function not currently used.
 */

parent.OAA_AE_TAB.isSidebarVisible = function () {
  var sidebar_window = document.getElementById("sidebar").contentWindow;
  return (sidebar_window.location.href == OAA_AE.SIDEBAR_URL);
};

/**
 * @function onTabSelect
 *
 * @memberOf OAA_AE
 *
 * @desc React to changing tab selection in browser window.
 */

parent.OAA_AE_TAB.onTabSelect = function () {

  var is_visible = parent.OAA_AE_TAB.isSidebarVisible();  
  var should_be_visible = parent.gBrowser.selectedTab.getAttribute(OAA_AE.TAB_ATTRIBUTE_NAME) == "true";
  
  if ((!is_visible && should_be_visible) || (is_visible && !should_be_visible))
    parent.toggleSidebar('ID_SIDEBAR_VIEW_OAA_ACCESSIBILITY_EXTENSION');
  else
    if (is_visible && parent.OAA_AE_TAB.updateContext) parent.OAA_AE_TAB.updateContext();
};

/**
 * @function closeSidebarIfOpen
 *
 * @memberOf OAA_AE
 *
 * @desc Used only at startup (when new window is opened) to avoid Firefox default behavior.
 */

OAA_AE.closeSidebarIfOpen = function () {

  OAA_AE.logger.debug("Is open: " + parent.OAA_AE_TAB.isSidebarVisible());
  
  if (parent.OAA_AE_TAB.isSidebarVisible()) toggleSidebar('ID_SIDEBAR_VIEW_OAA_ACCESSIBILITY_EXTENSION');
};

/**
 * @function getSidebarWindow
 *
 * @memberOf OAA_AE
 *
 * @desc Get the window of object of the sidebar
 *
 * @return window object | null
 */

OAA_AE.getSidebarWindow = function () {
  var sidebar_window = document.getElementById("sidebar").contentWindow;
  if (sidebar_window.location.href === OAA_AE.SIDEBAR_URL) return sidebar_window;
  return null;
};


/**
 * @function onLoad
 *
 * @memberOf OAA_AE
 *
 * @desc onload function sets toolbar and menu visibility
 */

OAA_AE.onLoad = function () {

  OpenAjax.a11y.setLogger(OAA_AE.getLogger("OAA-LIB", true));
  OAA_AE.logger = OAA_AE.getLogger("OAA-AE BROWSER", false);

  OAA_AE.initToolbarButtonAndMenu();

  parent.gBrowser.tabContainer.addEventListener("TabSelect", parent.OAA_AE_TAB.onTabSelect, false);
    
  // when new browser window opens...
  setTimeout(OAA_AE.closeSidebarIfOpen, 900);

};

window.addEventListener("load", OAA_AE.onLoad, false);
